using System;
using System.Collections.Generic;
using System.Linq;
using Uber.Core;
using Uber.Core.Model;
using Uber.Core.Repository;
using Uber.Core.Service;

namespace Uber.Service
{
    public class Posts : IPosts
    {
        private readonly IRepo<Post> postRepo;

        private readonly INotifications notifications;

        public Posts(IRepo<Post> postRepo, INotifications notifications)
        {
            this.postRepo = postRepo;
            this.notifications = notifications;
        }

        public IEnumerable<Post> GetSome(int page, int ps)
        {
            return postRepo.Where(o => o.ParentId == null)
                .OrderByDescending(x => x.CreationDate)
                .Pag(page, ps);
        }

        public void Edit(long id, string title, string body)
        {
            var p = postRepo.Get(id);
            p.Title = title;
            p.Body = body;
            postRepo.Save();
        }

        public Post Add(string body, long userId, long parentId)
        {
            var o = postRepo.Create();
            o.Body = body;
            o.OwnerId = userId;
            o.ParentId = parentId;
            o.CreationDate = DateTime.Now;
            o.Title = o.Body.Substring(0, 29) + " ...";
            postRepo.Add(o);
            postRepo.Save();

            notifications.NewAnswerAdded(parentId, userId, o.Id);

            return o;
        }

        public void Delete(long id)
        {
            var p = postRepo.Get(id);
            if (p == null) throw new UberEx("this post doesn't exist");
            if (p.Posts.Count > 0) throw new UberEx("this post has answers and it cannot be deleted");
            postRepo.Delete(id);
            postRepo.Save();
        }

        public long Ask(string title, string body, long userId)
        {
            var p = new Post { Title = title, Body = body, OwnerId = userId, CreationDate = DateTime.Now };
            postRepo.Add(p);
            postRepo.Save();
            return p.Id;
        }

        public Post Get(long id)
        {
            return postRepo.Get(id);
        }
    }
}